//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package main

import (
	"fmt"
	"net"
	"net/http"
	"os"

	gen_code_mongo "atomgit.com/openlinksaas-org/proxy/mongo_pkg/gen_code"
	impl_mongo "atomgit.com/openlinksaas-org/proxy/mongo_pkg/impl"
	gen_code_netutil "atomgit.com/openlinksaas-org/proxy/netutil_pkg/gen_code"
	impl_netutil "atomgit.com/openlinksaas-org/proxy/netutil_pkg/impl"
	gen_code_redis "atomgit.com/openlinksaas-org/proxy/redis_pkg/gen_code"
	impl_redis "atomgit.com/openlinksaas-org/proxy/redis_pkg/impl"
	gen_code_sql "atomgit.com/openlinksaas-org/proxy/sql_pkg/gen_code"
	impl_sql "atomgit.com/openlinksaas-org/proxy/sql_pkg/impl"
	gen_code_ssh "atomgit.com/openlinksaas-org/proxy/ssh_pkg/gen_code"
	impl_ssh "atomgit.com/openlinksaas-org/proxy/ssh_pkg/impl"

	"github.com/gorilla/mux"
)

func main() {
	if len(os.Args) < 2 {
		return
	}
	apiType := os.Args[1]
	l, err := net.Listen("tcp4", "127.0.0.1:")
	if err != nil {
		os.Stderr.Write([]byte(err.Error()))
		return
	}
	host := l.Addr().String()
	token := ""
	if apiType == "ssh" {
		token = impl_ssh.Init()
	} else if apiType == "redis" {
		token = impl_redis.Init()
	} else if apiType == "mongo" {
		token = impl_mongo.Init()
	} else if apiType == "sql" {
		token = impl_sql.Init()
	} else if apiType == "netutil" {
		token = impl_netutil.Init()
	}
	fmt.Printf("listen=%s,token=%s\n", host, token)

	var r *mux.Router
	if apiType == "ssh" {
		r = NewSshRouter(&SshApiDef{host},
			gen_code_ssh.NewConnectionAPIController(&impl_ssh.ConnectionApiImpl{}),
			gen_code_ssh.NewSftpAPIController(&impl_ssh.SftpApiImpl{}),
			gen_code_ssh.NewPortforwardAPIController(&impl_ssh.PortforwardApiImpl{}),
			gen_code_ssh.NewShellAPIController(&impl_ssh.ShellApiImpl{}),
		)
	} else if apiType == "redis" {
		r = NewRedisRouter(&RedisApiDef{host},
			gen_code_redis.NewConnectionAPIController(&impl_redis.ConnectionApiImpl{}),
			gen_code_redis.NewCmdAPIController(&impl_redis.CmdApiImpl{}))
	} else if apiType == "mongo" {
		r = NewMongoRouter(&MongoApiDef{host},
			gen_code_mongo.NewConnectionAPIController(&impl_mongo.ConnectionApiImpl{}),
			gen_code_mongo.NewDatabaseAPIController(&impl_mongo.DatabaseApiImpl{}),
			gen_code_mongo.NewCollectionAPIController(&impl_mongo.CollectionApiImpl{}),
		)
	} else if apiType == "sql" {
		r = NewSqlRouter(&SqlApiDef{host},
			gen_code_sql.NewConnectionAPIController(&impl_sql.ConnectionApiImpl{}),
			gen_code_sql.NewDatabaseAPIController(&impl_sql.DatabaseApiImpl{}),
			gen_code_sql.NewTableAPIController(&impl_sql.TableApiImpl{}),
		)
	} else if apiType == "netutil" {
		r = NewNetutilRouter(&NetutilApiDef{host},
			gen_code_netutil.NewDnsAPIController(&impl_netutil.DnsApiImpl{}),
			gen_code_netutil.NewIcmpAPIController(&impl_netutil.IcmpApiImpl{}),
			gen_code_netutil.NewScanAPIController(&impl_netutil.ScanApiImpl{}))
	}

	if r == nil {
		return
	}
	r.Methods("GET").PathPrefix("/").Name("swagger").Handler(&Web{})
	r.Methods("OPTIONS").PathPrefix("/").Name("options").Handler(&OptionsHandler{})
	s := &http.Server{
		Handler: r,
	}
	s.Serve(l)
}
